package com.lifeverse.repository;

import com.lifeverse.entity.SystemAlert;
import com.lifeverse.entity.enums.AlertSeverity;
import com.lifeverse.entity.enums.AlertStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 系统告警数据访问层
 */
@Repository
public interface SystemAlertRepository extends JpaRepository<SystemAlert, Long> {

    /**
     * 根据状态查询告警
     */
    List<SystemAlert> findByStatus(AlertStatus status);

    /**
     * 根据严重程度查询告警
     */
    List<SystemAlert> findBySeverity(AlertSeverity severity);

    /**
     * 根据告警源查询告警
     */
    List<SystemAlert> findBySource(String source);

    /**
     * 查询活跃告警
     */
    @Query("SELECT a FROM SystemAlert a WHERE a.status = 'ACTIVE' ORDER BY a.severity DESC, a.triggeredAt DESC")
    List<SystemAlert> findActiveAlerts();

    /**
     * 查询高优先级活跃告警
     */
    @Query("SELECT a FROM SystemAlert a WHERE a.status = 'ACTIVE' AND a.severity IN ('CRITICAL', 'FATAL') ORDER BY a.severity DESC, a.triggeredAt DESC")
    List<SystemAlert> findHighPriorityActiveAlerts();

    /**
     * 根据时间范围查询告警
     */
    @Query("SELECT a FROM SystemAlert a WHERE a.triggeredAt BETWEEN :startTime AND :endTime ORDER BY a.triggeredAt DESC")
    Page<SystemAlert> findByTimeRange(@Param("startTime") LocalDateTime startTime, 
                                     @Param("endTime") LocalDateTime endTime, 
                                     Pageable pageable);

    /**
     * 根据多个条件查询告警
     */
    @Query("SELECT a FROM SystemAlert a WHERE " +
           "(:status IS NULL OR a.status = :status) AND " +
           "(:severity IS NULL OR a.severity = :severity) AND " +
           "(:source IS NULL OR a.source LIKE %:source%) AND " +
           "a.triggeredAt BETWEEN :startTime AND :endTime " +
           "ORDER BY a.triggeredAt DESC")
    Page<SystemAlert> findByConditions(@Param("status") AlertStatus status,
                                      @Param("severity") AlertSeverity severity,
                                      @Param("source") String source,
                                      @Param("startTime") LocalDateTime startTime,
                                      @Param("endTime") LocalDateTime endTime,
                                      Pageable pageable);

    /**
     * 统计各状态的告警数量
     */
    @Query("SELECT a.status, COUNT(a) FROM SystemAlert a GROUP BY a.status")
    List<Object[]> countByStatus();

    /**
     * 统计各严重程度的告警数量
     */
    @Query("SELECT a.severity, COUNT(a) FROM SystemAlert a GROUP BY a.severity")
    List<Object[]> countBySeverity();

    /**
     * 统计各服务的告警数量
     */
    @Query("SELECT a.source, COUNT(a) FROM SystemAlert a WHERE a.triggeredAt >= :since GROUP BY a.source ORDER BY COUNT(a) DESC")
    List<Object[]> countBySourceSince(@Param("since") LocalDateTime since);

    /**
     * 查询长时间未解决的告警
     */
    @Query("SELECT a FROM SystemAlert a WHERE a.status IN ('ACTIVE', 'ACKNOWLEDGED') AND a.triggeredAt < :threshold ORDER BY a.triggeredAt ASC")
    List<SystemAlert> findLongRunningAlerts(@Param("threshold") LocalDateTime threshold);

    /**
     * 查询重复告警（相同规则名称和源）
     */
    @Query("SELECT a FROM SystemAlert a WHERE a.ruleName = :ruleName AND a.source = :source AND a.status = 'ACTIVE'")
    List<SystemAlert> findDuplicateAlerts(@Param("ruleName") String ruleName, @Param("source") String source);

    /**
     * 删除过期的已解决告警
     */
    @Query("DELETE FROM SystemAlert a WHERE a.status IN ('RESOLVED', 'CLOSED') AND a.resolvedAt < :threshold")
    void deleteResolvedAlertsBefore(@Param("threshold") LocalDateTime threshold);

    /**
     * 统计最近24小时的告警趋势
     */
    @Query("SELECT HOUR(a.triggeredAt) as hour, COUNT(a) as count " +
           "FROM SystemAlert a " +
           "WHERE a.triggeredAt >= :since " +
           "GROUP BY HOUR(a.triggeredAt) " +
           "ORDER BY hour")
    List<Object[]> getAlertTrendLast24Hours(@Param("since") LocalDateTime since);

    /**
     * 查询需要发送通知的告警
     */
    @Query("SELECT a FROM SystemAlert a WHERE a.notificationSent = false AND a.status = 'ACTIVE'")
    List<SystemAlert> findAlertsNeedingNotification();
}